﻿using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.Extensions.Logging;
using NP.BPMReportPlatform.AuthorizationProcessesManager;
using NP.BPMReportPlatform.AuthorizationProcessesManager.Dtos;
using NP.BPMReportPlatform.AuthorizationUserManager.Dtos;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Entities.BPM_Process;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Users = NP.BPMReportPlatform.Entities.BPM_Platform.Users;

namespace NP.BPMReportPlatform.AuthorizationUserManager
{
    public class UserAppService : BPMReportPlatformAppService, IUserAppService
    {
        private readonly SqlSugarClient _db, _dbPlatform, _dbProcess, _dbEngine;
        private readonly ILogger<UserAppService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        public UserAppService(ISqlSugarAppService sqlSugarAppService, ILogger<UserAppService> logger)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbProcess = sqlSugarAppService.GetProcessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<UserInfoOutput>> GetUserList(UserInfoInput input)
        {
            RefAsync<int> totalCount = 0;
            var listQueryable = GetQueryable(input);
            var userList = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            //返回结果
            return new PagedResultDto<UserInfoOutput>()
            {
                TotalCount = totalCount,
                Items = userList
            };
        }
        /// <summary>
        /// 导出用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UserInfoOutput>> ExportUserList(UserInfoInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }
        private ISugarQueryable<UserInfoOutput> GetQueryable(UserInfoInput input)
        {
            var listQueryable = _dbPlatform.Queryable<Users, UserExtension>(
                (u, ue) => new JoinQueryInfos(JoinType.Left, u.UserLoginId.Equals(ue.Loginname)))
                .WhereIF(!string.IsNullOrEmpty(input.UserLoginId), (u, ue) => u.UserLoginId.Contains(input.UserLoginId))
                .WhereIF(!string.IsNullOrEmpty(input.UserName), (u, ue) => u.UserName.Contains(input.UserName))
                .WhereIF(!string.IsNullOrEmpty(input.MobilePhone), (u, ue) => u.MobilePhone.Contains(input.MobilePhone) || ue.Mobile.Contains(input.MobilePhone))
                .WhereIF(input.Status.HasValue, (u, ue) => u.Status.Equals(input.Status))
                .WhereIF(!string.IsNullOrEmpty(input.WorkNumber), (u, ue) => u.WorkNumber.Contains(input.WorkNumber))
                .WhereIF(!string.IsNullOrEmpty(input.UserType), (u, ue) => u.UserType.Equals(input.UserType))
                .Select((u, ue) => new UserInfoOutput
                {
                    UserId = u.UserId,
                    UserLoginId = u.UserLoginId,
                    UserName = u.UserName,
                    Gender = u.Gender,
                    Email = u.Email,
                    WorkNumber = u.WorkNumber,
                    Status = u.Status,
                    FullPathText = u.FullPathText,
                    FullPathCode = u.FullPathCode,
                    Mobile = SqlFunc.IsNullOrEmpty(ue.Mobile) ? u.MobilePhone : ue.Mobile,
                    Sapcompanycode = ue.Sapcompanycode,
                    Sapcompanyname = ue.Sapcompanyname,
                    Sapcostcentercode = ue.Sapcostcentercode,
                    Sapcostcenter = ue.Sapcostcenter,
                    Org = ue.Org,
                    Orgname = ue.Orgname,
                    Employeepost = ue.Employeepost,
                    Employeepostname = ue.Employeepostname,
                    Poste = ue.Poste,
                    Posnc = ue.Posnc,
                    Bossemployeeid = ue.Bossemployeeid,
                    Bossname = ue.Bossname,
                    Province = ue.Province,
                    Cityname = ue.Cityname,
                    StatusName = u.Status == 1 ? "有效" : "无效",
                    CreateDate = u.CreateDate,
                    UserType = u.UserType,
                    UserTypeName = u.UserType == "E" ? "员工" : (u.UserType == "S" ? "系统账户" : (u.UserType == "C" ? "顾问" : "")),
                    GenderName = u.Gender == "F" ? "女" : (u.Gender == "M" ? "男" : "")
                }).MergeTable().OrderBy(x => x.CreateDate, OrderByType.Desc);

            return listQueryable;
        }

        /// <summary>
        /// 编辑外部用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> EditOuterUserAsync(EditOuterUserInfo input)
        {
            if (string.IsNullOrEmpty(input.UserLoginId))
            {
                throw new Exception("请填写域账号");
            }
            if (string.IsNullOrEmpty(input.UserName))
            {
                throw new Exception("请填写姓名");
            }
            if (string.IsNullOrEmpty(input.Email))
            {
                throw new Exception("请填写邮箱");
            }
            if (string.IsNullOrEmpty(input.Gender))
            {
                throw new Exception("请选择性别");
            }
            if (string.IsNullOrEmpty(input.WorkNumber))
            {
                throw new Exception("请填写工号");
            }

            var currentUser = await _dbPlatform.Queryable<Users>().FirstAsync(x => x.WorkNumber == CurrentUser.UserName);

            RefAsync<string> res = "编辑成功！";
            var entity = input.UserId == Guid.Empty ? null : _dbPlatform.Queryable<Users>().Where(x => x.UserId.Equals(input.UserId)).First();
            if (entity == null)
            {
                if (_dbPlatform.Queryable<Users>().Any(x => x.UserLoginId.Equals(input.UserLoginId)))
                {
                    throw new Exception("域账号已存在");
                }
                if (_dbPlatform.Queryable<Users>().Any(x => x.WorkNumber.Equals(input.WorkNumber)))
                {
                    throw new Exception("工号已存在");
                }
                entity = new Users
                {
                    UserId = Guid.NewGuid(),
                    UserLoginId = input.UserLoginId,
                    UserName = input.UserName,
                    Password = "fCIvspJ9goryL1khNOiTJIBjfA0=",
                    UserType = "C",
                    Gender = input.Gender,
                    Email = input.Email,
                    Status = 1,
                    CreateDate = DateTime.Now,
                    WorkNumber = input.WorkNumber,
                    CreateUserId = currentUser?.UserId
                };
                await _dbPlatform.Insertable(entity).ExecuteCommandAsync();
                res = "添加成功！";
            }
            else
            {
                if (input.Status == null)
                {
                    throw new Exception("请填写状态");
                }
                if (_dbPlatform.Queryable<Users>().Any(x => x.UserLoginId.Equals(input.UserLoginId) && x.UserId != input.UserId))
                {
                    throw new Exception("域账号已存在");
                }
                if (_dbPlatform.Queryable<Users>().Any(x => x.WorkNumber.Equals(input.WorkNumber) && x.UserId != input.UserId))
                {
                    throw new Exception("工号已存在");
                }                
                entity.UserLoginId = input.UserLoginId;
                entity.UserName = input.UserName;
                entity.Gender = input.Gender;
                entity.Status = input.Status;
                entity.Email = input.Email;
                entity.WorkNumber = input.WorkNumber;
                entity.ModifyDate = DateTime.Now;
                entity.MidifyUserId = CurrentUser?.Id;
                await _dbPlatform.Updateable(entity).WhereColumns(x => x.UserId).ExecuteCommandAsync();
            }
            return res;
        }

        /// <summary>
        /// 删除外部用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Task DeleteOuterUserAsync(Guid id)
        {
            return _dbPlatform.Deleteable<Users>().Where(x => x.UserId.Equals(id) && x.UserType.Equals("C")).ExecuteCommandAsync();
        }
    }
}
